package com.small.common.manager.redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @Description Jedis客户端接口
 * @Author DingYou
 * @Date 2018-07-10 11:42
 * @Version 1.0
 */
public interface RedisClient {
    /**
     * 执行function中的逻辑
     *
     * @param function
     * @param <T>
     * @return
     */
    <T> T execute(Function<Jedis, T> function);

    /**
     * 执行consumer中的逻辑
     * @param consumer
     */
    void consume(Consumer<Jedis> consumer);

    String set(final String key, final Object value);

    /**
     * set值,同时设置过期时间,单位秒
     *
     * @param key
     * @param value
     * @param time
     * @return
     */
    String set(final String key, final Object value, final int time);

    /**
     * 完全自主的set方法
     *
     * @param key
     * @param value
     * @param nxxx  nxxx NX|XX, NX -- Only set the key if it does not already exist. XX -- Only set the key
     * @param expx  expx EX|PX, expire time units: EX = seconds; PX = milliseconds
     * @param time  time expire time in the units of {@param #expx}
     * @return
     */
    String set(final String key, final Object value, final String nxxx, final String expx,
               final int time);

    /**
     * 获取String型value
     *
     * @param key
     * @return
     */
    String get(String key);

    /**
     * 获取<T>型value
     *
     * @param key
     * @param clazz
     * @param <T>
     * @return
     */
    <T> T get(String key, Class<T> clazz);

    /**
     * 获取元素类型为<T>的List类型value
     *
     * @param key
     * @param clazz
     * @param <T>
     * @return
     */
    <T> List<T> getList(String key, Class<T> clazz);

    /**
     * 获取Map型value
     * @param key
     * @param keyType
     * @param valueType
     * @param <K>
     * @param <V>
     * @return
     */
    <K, V> Map<K, V> getMap(String key, Class<K> keyType, Class<V> valueType);

    /**
     * 设置过期时间,单位毫秒
     *
     * @param key
     * @param milliseconds
     * @return
     */
    Long pexpire(final String key, final long milliseconds);

    /**
     * 设置指定单位的过期时间,最小到毫秒
     *
     * @param key
     * @param times
     * @param timeUnit
     * @return
     */
    Long pexpire(final String key, final long times, final TimeUnit timeUnit);

    /**
     * 设置过期时间,单位秒
     *
     * @param key
     * @param seconds
     * @return
     */
    Long expire(final String key, final int seconds);

    /**
     * 是否存在key
     *
     * @param key
     * @return
     */
    Boolean exists(final String key);

    /**
     * 设置hash型数据
     *
     * @param key
     * @param field
     * @param value
     * @return
     */
    Long hset(final String key, final String field, final Object value);

    /**
     * 删除hash中的指定字段
     *
     * @param key
     * @param fields
     * @return
     */
    Long hdel(final String key, final String... fields);

    /**
     * 获取hash中的String类型的value
     *
     * @param key
     * @param field
     * @return
     */
    String hget(final String key, final String field);

    /**
     * 获取hash中T型的value
     *
     * @param key
     * @param field
     * @param clazz
     * @param <T>
     * @return
     */
    <T> T hget(final String key, final String field, Class<T> clazz);

    /**
     * hash中指定字段自增指定值
     *
     * @param key
     * @param field
     * @param value
     * @return
     */
    Long hincrBy(final String key, final String field, final long value);

    /**
     * 获取hash中元素为T型的List型value
     *
     * @param key
     * @param field
     * @param clazz
     * @param <T>
     * @return
     */
    <T> List<T> hgetList(final String key, final String field, Class<T> clazz);

    /**
     * 删除key
     *
     * @param keys
     */
    Long del(String... keys);

    /**
     * 添加元素进set
     *
     * @param key
     * @param members
     * @return
     */
    Long sadd(final String key, final Object... members);

    /**
     * 从set中弹出一个元素
     *
     * @param key
     * @return
     */
    String spop(final String key);

    /**
     * 从set中弹出一个元素并转成目标类型
     *
     * @param key
     * @return
     */
    <T> T spop(final String key, Class<T> clazz);

    /**
     * 从set中弹出一批元素
     *
     * @param key
     * @param count
     * @return
     */
    Set<String> spop(final String key, final long count);

    /**
     * 从set中弹出一批元素
     *
     * @param key
     * @param count
     * @return
     */
    <T> Set<T> spop(final String key, final long count, Class<T> clazz);

    /**
     * 获取set中所有的元素
     * @param key
     * @return
     */
    Set<String> smembers(final String key);

    /**
     * 获取set中所有的成员, 并转成目标类型
     * @param key
     * @param clazz
     * @param <T>
     * @return
     */
    <T> Set<T> smembers(final String key, Class<T> clazz);

    /**
     * 判断value是否是set的成员
     * @param key
     * @param value
     * @return
     */
    boolean sismember(final String key, final Object value);

    /**
     * @Author: yinhaijun
     * @Description: 查询hash下所有的key-value
     * @Date: 2018/8/31 15:22
     * @param: s
     * @return:
     * @version: 1.2
     **/
    Map<String, String> hgetAll(String key);

    /**
     * 获取list最后一个元素, 获取不到就阻塞
     *
     * @param key
     * @return
     */
    String brpop(final String key);

    /**
     * 获取list最后一个元素, 获取不到就阻塞
     *
     * @param key
     * @param clazz
     * @param <T>
     * @return
     */
    <T> T brpop(final String key, final Class<T> clazz);

    /**
     * 将value从左侧插入list
     *
     * @param key
     * @param values
     * @return
     */
    Long lpush(final String key, Object... values);

    /**
     * 循环扫描redis中符合pattern的key,用来替代keys命令,谨慎调用
     * @param pattern
     * @return
     */
    List<String> scan(String pattern);

    /**
     * 循环扫描redis中的指定条件的key,用来替代keys命令,谨慎调用
     * @param cursor
     * @param scanParams
     * @return
     */
    ScanResult<String> scan(String cursor, ScanParams scanParams);
}
